<?php
/**
 * @file: xunsearchm.php
 * @User: shiwuhao
 * @Date: 16/1/5 19:54
 * @synopsis: xunSearch model类
 */

defined('BASEPATH') OR exit('No direct script access allowed');

require_once('/usr/local/xunsearch/sdk/php/lib/XS.php');

class Xunsearchuserm extends CI_Model
{
    // xunSearch 实例
    public $xunSearch  = NULL;
    // 配置文件目录路径
    public $iniDirPath = '/usr/local/xunsearch/sdk/php/app/';
    // 配置文件名称
    public $iniName    = 'user.ini';
    // 配置文件绝对路径
    public $iniPath    = '';

    public function __construct($iniName = '')
    {
        if ($iniName) $this->iniName = $iniName;

        $this->iniPath = $this->iniDirPath.$this->iniName;

        if ($this->xunSearch == NULL) {
            $this->xunSearch = new XS($this->iniPath);
        }

        $this->load->helper('url');
    }

    /**
     * 建立索引
     */
    public function buildIndex($type = '', $page = 1, $per_page)
    {
        if ($type == 'user') { // 用户
            $this->buildIndex_user($page, $per_page);
        } else {
            exit('type 参数错误2');
        }
    }

    /**
     * 用户数据添加到索引
     * @param int $page
     * @param $per_page
     */
    private function buildIndex_user($page = 1, $per_page)
    {
        $index = $this->xunSearch->index;

        if (!$per_page) $per_page = 1000;

        $start = ($page - 1) * $per_page;

        $list = $this->db->select('id,username,truename,practice_hospital,thread,user_level,verified_status,add_time')
            ->from('ml_fellow')
            ->where(array('id >' => $start))
            ->limit($per_page)
            ->order_by('id', 'ASC')
            ->get()
            ->result_array();

        //echo $this->db->last_query();
        if (!$list) {
            exit('success');
        }

        $index->openBuffer();
        foreach($list as $k => $v) {
            $item = array();
            $item['id']                 = $v['id'];
            $item['username']           = $v['username'];
            $item['truename']           = $v['truename'];
            $item['hospital']           = $v['practice_hospital'];
            $item['hospital_str_len']   = mb_strlen($v['practice_hospital'], 'utf8');// 医院名称长度
            $item['thread']             = $v['thread'];
            $item['user_level']         = $v['user_level'];
            $item['verified_status']    = $v['verified_status'] == 3 || $v['verified_status'] == 5 ? 1 : 0;
            $item['add_time']           = $v['add_time'];

            $doc = new XSDocument;
            $doc   -> setFields($item);
            $index -> add($doc);
        }
        $index->closeBuffer();
    }

    /**
     * 添加单条用户信息到索引
     */
    public function addOneUser($data = array())
    {
        $index = $this->xunSearch->index;
        $item['id']                 = $data['id'];
        $item['username']           = $data['username'];
        $item['truename']           = $data['truename'];
        $item['hospital']           = $data['hospital'];
        $item['hospital_str_len']   = mb_strlen($data['hospital'], 'utf8');// 医院名称长度
        $item['thread']             = $data['thread'];
        $item['user_level']         = $data['user_level'];
        $item['verified_status']    = $data['verified_status'];
        $item['add_time']           = $data['add_time'];

        $doc = new XSDocument;
        $doc   -> setFields($item);
        return $index -> add($doc);
    }

    /**
     * 搜索单条信息
     * @param $query
     * @return mixed
     */
    public function search($query)
    {
        $search = $this->xunSearch->search;
        $info =$search
            -> setAutoSynonyms(true)
            -> setQuery($query)
            -> setLimit(1000)
            -> search();
        return $info;
    }

    /**
     * 更新单条用户信息
     * @param array $data
     * @return bool
     */
    public function updateOneUser($data = array())
    {
        if (!$data) return false;
        $index = $this->xunSearch->index;
        $doc = new XSDocument;
        $doc -> setFields($data);
        return $index -> update($doc);
    }

    /**
     * 根据关键词取出数据 科室信息 用户信息
     * @param string $keywords
     */
    public function getList($keywords = '', $page = 1, $per_page = 10)
    {
        if (!$keywords) return array('count' => 0, 'list' => array());
        $start = ($page - 1) * $per_page;

        $search = $this->xunSearch->search;

        // 获取分组下 科室信息
        $thread_list = self::getThreadList($keywords);

        $user = self::getUserList($keywords, $page, $per_page);

        $response = array('thread' => $thread_list, 'user' => $user);
        return $response;
    }

    /**
     * 根据关键词获取该医院下面的所有专家
     * @param string $keywords
     * @return array
     */
    public function getExpertList($keywords = '')
    {
        $search = $this->xunSearch->search;
        $hospital_name = self::getOneHospitalName($keywords);
        $query = "hospital:{$hospital_name} AND user_level:5";
        $user_list = $search
            -> setAutoSynonyms(true)
            -> setQuery($query)
            -> search();
        return $user_list;
    }

    /**
     * 更具关键词 获取 用户信息
     * @param string $keywords
     * @param int $page
     * @param int $per_page
     * @return array
     */
    public function getUserList($keywords = '', $page = 1, $per_page = 10)
    {
        $start = ($page - 1) * $per_page;
        $search = $this->xunSearch->search;
        $sorts = array('user_level' => false, 'verified_status' => false, 'add_time' => false);
        $user_list = $search
            -> setAutoSynonyms(true)
            -> setQuery("username:$keywords OR truename:$keywords")
            //-> setQuery("username:$keywords")
            -> setMultiSort($sorts)
            -> setLimit($per_page, $start)
            -> search();
        $user_count = $search->lastCount;
        return array('list' => $user_list, 'count'=>$user_count);
    }

    /**
     * 搜索医院信息 返回一条医院信息的名称
     * @param string $keywords
     * @param int $per_page
     * @param int $page
     */
    public function getOneHospitalName($keywords = '', $page = 1,$per_page = 10)
    {
        $start = ($page - 1) * $per_page;

        $search = $search = $this->xunSearch->search;
        $hospital = $search
            -> setAutoSynonyms(true)
            -> setQuery("hospital:$keywords")
            -> setLimit($per_page, $start)
            -> search();
        return $hospital[0]->hospital;
    }

    /**
     * 根据医院名称获取科室信息 并获取科室下用户信息
     * @param $hospital_name
     */
    public function getThreadList($keywords)
    {
        $hospital_list = array();
        $hospital_name = self::getOneHospitalName($keywords);

        if (!$hospital_name) return $hospital_list;

        // 使用医院字符长度来精确搜索
        $hospital_str_len = utf8_strlen($hospital_name);

        $search = $search = $this->xunSearch->search;

        // 根据thread字段分面搜索
        $list = $search
            -> setAutoSynonyms(true)
            -> setQuery("hospital:$keywords AND hospital_str_len:$hospital_str_len")
            -> setFacets(array('thread'))
            -> search();
        $group = $search->getFacets('thread');

        if (!$group) return $hospital_list;

        $sorts = array('user_level' => false, 'verified_status' => false, 'add_time' => false);

        //取出分组下用户信息
        foreach($group as $k => $v){
            $user_list = $search->setQuery("(hospital:$keywords AND thread:$k) NOT (user_level:5)")->setMultiSort($sorts)->setLimit(3)->search();
            if (!$user_list) {
                unset($hospital_list[$k]);
            } else {
                $hospital_list[$k]['user_list']  = $user_list;
                $hospital_list[$k]['user_count'] = $search->lastCount;
            }
        }

        return $hospital_list;
    }

    /**
     * 获取医院科室下 更多用户信息
     * @param $keywords
     * @param $thread
     */
    public function getThreadUserList($keywords, $thread, $page = 1, $per_page = 10)
    {
        $search = $search = $this->xunSearch->search;
        $start = ($page - 1) * $per_page;
        $sorts = array('user_level' => false, 'verified_status' => false, 'add_time' => false);
        $hospital_str_len = utf8_strlen($keywords);
        $user_list = $search
            -> setAutoSynonyms(true)
            -> setQuery("(hospital:$keywords AND thread:$thread) NOT (user_level:5)")
            -> setMultiSort($sorts)
            -> setLimit($per_page, $start)
            -> search();

        $user_count = $search->lastCount;
        return array('list' => $user_list, 'count'=>$user_count);
    }

    /**
     * 清空索引
     */
    public function clearIndex()
    {
        $index  = $this->xunSearch->index;
        $res = $index->clean();
        exit('clear success');
    }
}